<?php

	namespace org\tekuna\core\plugin;
	
	use org\tekuna\base\Tekuna;

	use org\tekuna\core\context\Context;
	use org\tekuna\core\configuration\XmlConfiguration;
	use org\tekuna\core\configuration\Configured;
	use org\tekuna\core\configuration\ConfigurationElement;

	
	abstract class Plugin implements Configured {
		
		const
			PLUGIN_CONFIGURATION_FILE = 'tekuna-plugin.xml';
		
		protected
			$objPluginConfigurationElement = NULL,
			$objPluginConfiguration = NULL,
			$sKey = '',
			$sVersion = '',
			$sTekunaVersion = '',
			$arrPluginDependencies = array();
			
			
		protected function loadPluginConfiguration($sConfigFile) {
			
			if (! is_file($sConfigFile)) {
				
				throw new PluginException("The plugin configuration file '$sConfigFile' does not exist.");
			}
			
			// load the configuration
			$this -> objPluginConfiguration = new XmlConfiguration($sConfigFile);
			$this -> objPluginConfiguration -> loadConfiguration(new Context());
			
			// load the metadata
			$this -> loadPluginMetadata();
		}
		
		
		protected function loadPluginMetadata() {
			
			// init plugin metadata
			$this -> sKey = $this -> objPluginConfiguration -> getRootElement() -> getAttribute('plugin', 'key') -> getValue();
			$this -> sVersion = $this -> objPluginConfiguration -> getRootElement() -> getAttribute('plugin', 'version') -> getValue();
			$this -> sTekunaVersion = $this -> objPluginConfiguration -> getRootElement() -> getAttribute('plugin', 'tekuna-version') -> getValue();
			
			// load plugin dependencies
			$arrDependencyElements = $this -> objPluginConfiguration -> getRootElement() -> getAllChildElements('plugin', 'required-plugin');
			foreach ($arrDependencyElements as $objDependencyElement) {
				
				$sRequiredPluginKey = $objDependencyElement -> getAttribute('plugin', 'key') -> getValue();
				$sRequiredPluginVersion = $objDependencyElement -> getAttribute('plugin', 'version') -> getValue();
				
				if (isset($this -> arrPluginDependencies[$sRequiredPluginKey])) {
					
					throw new PluginException("The plugin dependency '$sRequiredPluginKey' for plugin '$this->sKey' is defined more than once.");
				}
				
				$this -> arrPluginDependencies[$sRequiredPluginKey] = $sRequiredPluginVersion;
			}
		}
		
		public function getPluginDependencies() {
			
			return $this -> arrPluginDependencies;
		}
		
		public function getPluginConfig() {
			
			return $this -> objPluginConfiguration;
		}
		
		public function setConfigurationElement(ConfigurationElement $objElement) {
			
			$this -> objPluginConfigurationElement = $objElement;
		}
		
		public function getConfigurationElement() {
			
			return $this -> objPluginConfigurationElement;
		}
		
		
		abstract function getResourceFilename($sResourcePath);
		
		abstract function getPluginClassLoader();		
		
		abstract function __toString();
		
		
		public function getKey() {
			
			return $this -> sKey;
		}
		
		public function getVersion() {
			
			return $this -> sVersion;
		}
		
		public function getTekunaVersion() {
			
			return $this -> sTekunaVersion;
		}
	}

